package com.qhx.backme.util;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.qhx.backme.exception.WeBaseFrontException;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * http工具类
 *
 * @author: qhx20040819
 * @date: 2023-10-20 14:20
 **/
@Component
@Slf4j
public class HttpUtil {

    // 从配置文件中获取合约相关参数
    @Value("${contract.url}")
    public  String URL;
    @Value("${contract.address}")
    public  String CONTRACT_ADDRESS;
    @Value("${contract.name}")
    public  String CONTRACT_NAME;
    @Value("${contract.abi}")
    public  String CONTRACT_ABI;
    @Value("${address.owner}")
    public String OWNER_ADDRESS;

    /**
     * 构建合约请求参数并发送请求
     *
     * @param userAddress 用户地址
     * @param funcName    合约函数名
     * @param params      合约函数参数列表
     * @return 请求结果字符串
     */
    public  String contractRequest(String userAddress, String funcName, List<Object> params){
        // 构建请求体
        JSONObject requestBody = new JSONObject();
        requestBody.putOpt("contractName",CONTRACT_NAME);
        requestBody.putOpt("contractAddress",CONTRACT_ADDRESS);
        requestBody.putOpt("contractAbi",JSONUtil.parseArray(CONTRACT_ABI));
        requestBody.putOpt("funcName",funcName);
        requestBody.putOpt("funcParam",params);
        requestBody.putOpt("user",userAddress);
        requestBody.putOpt("groupId",1);
        requestBody.putOpt("version","");
        requestBody.putOpt("useAes",false);
        requestBody.putOpt("useCns",false);
        requestBody.putOpt("cnsName","");

        // 发送请求并返回结果
        return httpPost(requestBody.toString());
    }

    /**
     * 调用合约函数（默认使用所有者地址）
     *
     * @param funcName 合约函数名
     * @param params   合约函数参数列表
     * @return 解析后的JSON数组结果
     */
    public JSONArray call(String funcName, List<Object> params){
        return call(OWNER_ADDRESS,funcName,null);
    }

    /**
     * 调用合约函数
     *
     * @param userAddress 用户地址
     * @param funcName    合约函数名
     * @param params      合约函数参数列表
     * @return 解析后的JSON数组结果
     */
    public JSONArray call(String userAddress, String funcName, List<Object> params)
    {
        String response = contractRequest(userAddress, funcName, params);
        try
        {
            JSONArray resJson = JSONUtil.parseArray(response);
            return resJson;
        } catch (Exception e)
        {
            throw new WeBaseFrontException(response);
        }
    }

    /**
     * 发送交易（默认使用所有者地址）
     *
     * @param funcName 合约函数名
     * @param params   合约函数参数列表
     * @return 交易结果字符串
     */
    public String sendTransaction(String funcName, List<Object> params)
    {
        return sendTransaction(OWNER_ADDRESS,funcName,params);
    }

    /**
     * 发送交易
     *
     * @param userAddress 用户地址
     * @param funcName    合约函数名
     * @param params      合约函数参数列表
     * @return 交易结果字符串，成功时返回null，否则返回错误信息
     */
    public String sendTransaction(String userAddress, String funcName, List<Object> params)
    {
        String response = contractRequest(userAddress, funcName, params);
        try
        {
            JSONObject resJson = JSONUtil.parseObj(response);
            if (resJson.getBool("statusOK"))
            {
                return null;
            } else
            {
                return resJson.getStr("message");
            }
        } catch (Exception e)
        {
            throw new WeBaseFrontException(response);
        }
    }

    /**
     * 发送 post 请求
     *
     * @param jsonStr Form表单json字符串
     * @return 请求结果
     */
    private  String httpPost(String jsonStr) {
        // 创建HttpClient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // 创建HttpPost对象
        HttpPost httpPost = new HttpPost(URL);
        // 封装消息实体
        StringEntity stringEntity = new StringEntity(jsonStr, StandardCharsets.UTF_8);
        stringEntity.setContentEncoding("utf-8");
        stringEntity.setContentType("application/json");
        httpPost.setEntity(stringEntity); // 设置消息实体
        CloseableHttpResponse httpResponse = null;
        String result = null;
        try {
            httpResponse = httpClient.execute(httpPost); // 执行请求，获得响应对象
            result = EntityUtils.toString(httpResponse.getEntity(), "UTF-8"); // 获得响应消息实体
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }


}
